package com.example.elderlycare.controller;

import com.example.elderlycare.controller.entity.RosterRequestBody;
import com.example.elderlycare.dao.entity.Roster;
import com.example.elderlycare.service.RosterService;
import com.example.elderlycare.service.entity.QueryListResponseBody;
import com.example.elderlycare.service.entity.RosterItem;
import com.example.elderlycare.service.entity.RosterStatisticsResponseBody;
import com.example.elderlycare.utils.DateUtil;
import com.example.elderlycare.utils.Result;
import com.example.elderlycare.utils.ResultEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/roster")
public class RosterController {
    private final Logger logger = LoggerFactory.getLogger(RosterController.class);

    @Resource
    RosterService rosterService;

    @PostMapping("/doRoster")
    public Result<?> doRoster(
            @RequestParam(value = "file", required = false) MultipartFile file,
            @RequestParam(value = "id", required = false) List<Integer> ids,
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime
    ) {
        try {
            Map<String, Object> params = new HashMap<>();
            if (startTime != null) {
                Date startDate = DateUtil.getDateFromString(startTime);
                params.put("startTime", startDate);
            }
            if (endTime != null) {
                Date endDate = DateUtil.getDateFromString(endTime);
                params.put("endTime", endDate);
            }
            if (file != null) {
                params.put("file", file);
            }
            if (ids != null) {
                params.put("ids", ids);
            }
            List<Roster> rosterList = rosterService.generateRosterRecord(params);
            boolean success = rosterService.saveBatch(rosterList);
            if (!success) {
                return Result.error(ResultEnum.DEFAULT_ERROR);
            }
            return Result.success(null);
        } catch (ParseException | IOException e) {
            e.printStackTrace();
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }


    @PostMapping
    public Result<?> addRoster(@Valid @RequestBody RosterRequestBody.AddRosterRequestBody params) {
        Roster roster = Roster.builder().
                dutyAt(params.getTime()).
                type(params.getType()).
                absent(params.getAbsent()).
                isLeave(params.getLeave()).
                employeeId(params.getEmployeeId()).
                build();
        boolean success = rosterService.save(roster);
        if (!success) {
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
        return Result.success(null);
    }


    @PostMapping("/v1")
    public Result<?> addRosterBatch(@Valid @RequestBody RosterRequestBody.AddRosterBatchRequestBody req) {
        int count = 0;
        List<RosterRequestBody.AddRosterItem> items = req.getItems();
        for (RosterRequestBody.AddRosterItem item : items) {
            Roster roster = Roster.builder().
                    employeeId(req.getEmployeeId()).
                    dutyAt(item.getTime()).
                    type(item.getType()).
                    absent(item.getAbsent()).
                    isLeave(item.getLeave()).
                    absent(item.getAbsent()).build();
            boolean success = rosterService.save(roster);
            if (!success) {
                count++;
            }
        }
        if (count != 0) {
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
        return Result.success(null);
    }


    @PutMapping
    public Result<?> updateRoster(@Valid @RequestBody RosterRequestBody.UpdateRosterRequestBody params) {
        Roster roster = Roster.builder().
                id(params.getId()).
                dutyAt(params.getTime()).
                type(params.getType()).
                absent(params.getAbsent()).
                isLeave(params.getLeave()).
                employeeId(params.getEmployeeId()).
                build();
        boolean success = rosterService.updateById(roster);
        if (!success) {
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
        return Result.success(null);
    }

    @GetMapping
    public Result<QueryListResponseBody<RosterItem>> queryRoster(
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime,
            @RequestParam(value = "employee", required = false) String employee,
            @RequestParam(defaultValue = "10", value = "pageSize") int pageSize,
            @RequestParam(defaultValue = "1", value = "current") int current
    ) {
        Map<String, Object> params = new HashMap<>();
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        params.put("employee", employee == null ? null : "%" + employee + "%");
        params.put("limit", pageSize);
        params.put("offset", (current - 1) * pageSize);
        QueryListResponseBody<RosterItem> responseBody = rosterService.queryRosterList(params);
        return Result.success(responseBody);
    }

    @DeleteMapping
    public Result<?> deleteRoster(@Valid @RequestParam("ids") List<Integer> ids) {
        boolean success = rosterService.removeByIds(ids);
        if (!success) {
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
        return Result.success(null);
    }

    @GetMapping("/count")
    public Result<QueryListResponseBody<RosterStatisticsResponseBody>> getRosterStatistics(
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime,
            @RequestParam(value = "name", required = false) String name
    ) {
        Map<String, Object> params = new HashMap<>();
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        params.put("name", name == null ? null : "%" + name + "%");

        QueryListResponseBody<RosterStatisticsResponseBody> responseBody = rosterService.queryRosterStatisticsList(params);

        return Result.success(responseBody);
    }


    @GetMapping("/template")
    public Result<?> getTemplate(HttpServletResponse response) {
        try {
            rosterService.getImportTemplate(response);
            return Result.success(null);
        } catch (IOException e) {
            logger.warn("IOException ", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }
}
